/*******************************************************************************
 * 版权：北京润尼尔网络科技有限公司，保留所有版权<br>
 * 版本：v1.0.0<br>
 * 文件：InteractiveManhattanRouter.js<br>
 * 日期：2016年10月1日<br>
 * 作者: 王志远<br>
 * 功能：交互ManhattanRouter<br>
 * 
 * 修改记录：<br>
 * 日期 描述 更新功能<br>
 ******************************************************************************/

window.makeNamespace(window,"Rainier.UI.V2");


/**
 * 类型名称：Rainier.UI.V2.InteractiveManhattanRouter<br>
 * 类型功能：交互ManhattanRouter<br>
 */
//Rainier.UI.V2.InteractiveManhattanRouter = draw2d.layout.connection.MuteableManhattanConnectionRouter.extend({
//Rainier.UI.V2.InteractiveManhattanRouter = draw2d.layout.connection.SplineConnectionRouter.extend({
//Rainier.UI.V2.InteractiveManhattanRouter = draw2d.layout.connection.CircuitConnectionRouter.extend({
//Rainier.UI.V2.InteractiveManhattanRouter = draw2d.layout.connection.ManhattanBridgedConnectionRouter.extend({
//Rainier.UI.V2.InteractiveManhattanRouter = draw2d.layout.connection.ManhattanConnectionRouter.extend({
Rainier.UI.V2.InteractiveManhattanRouter = draw2d.layout.connection.InteractiveManhattanConnectionRouter.extend({
	
	NAME : "Rainier.UI.V2.InteractiveManhattanRouter",
	
	/**
	 * 函数名称：Rainier.UI.V2.InteractiveManhattanRouter.init<br>
	 * 函数功能：构造函数<br>
	 * 异常信息：无<br>
	 */
    init: function(){
        this._super();
        this.MINDIST = 0;
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.InteractiveManhattanRouter.onInstall<br>
	 * 函数功能：安装编辑策略<br>
	 * 参数输入：connection:draw2d.Connection<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
    onInstall: function(conn){
    	var policy = new Rainier.UI.V2.OrthogonalSelectionFeedbackPolicy();
        conn.installEditPolicy(policy);
        if(!conn._routingMetaData){
            conn._routingMetaData = {
                routedByUserInteraction:false,
                fromDir:-1,
                toDir:-1,
                firstRoute : true
            };
        }
    },
    
    /**
	 * 函数名称：Rainier.UI.V2.InteractiveManhattanRouter.onDrag<br>
	 * 函数功能：执行Drag操作<br>
	 * 参数输入：figure:connction<br>
	 * 参数输入：dx, dy, dx2, dy2:Number<br>
	 * 函数返回：<br>
	 * 异常信息：<br>
	 */
    onDrag : function(figure, dx, dy, dx2, dy2){
    	this._super(figure, dx, dy, dx2, dy2);
    },
    
	/**
	 * 函数名称：Rainier.UI.V2.InteractiveManhattanRouter.init<br>
	 * 函数功能：绘制线条<br>
	 * 参数输入：conn:draw2d.Connection<br>
	 * 参数输入：routingHints:连接提示<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
    route: function(conn, routingHints){
    	
    	//如果routingHints为空或未定义则抛出异常
    	if (!routingHints.oldVertices) {
            debugger
        }
    	var oldVertices = routingHints.oldVertices;
        var vertexCount  = oldVertices.getSize();
        
		var source  = conn.getSource();
		var target  = conn.getTarget();
		
        var fromPt  = conn.getStartPoint();
        var fromDir = source.getConnectionDirection( conn.getTarget());

        var toPt    = conn.getEndPoint();
        var toDir   = target.getConnectionDirection( conn.getSource());
    	
    	//如果刚刚创建连接则，直接添加顶点
    	if(conn._routingMetaData.firstRoute){
    		oldVertices.each(function(i,p){
    			conn.addPoint(p);
    		});
    		conn._routingMetaData.firstRoute = false;
    		this._paint(conn);
    		conn.saveOldSegments();
    		return;
    	} 
    	
    	//如果拖拽多个元件中间存在本连线
    	if(conn.isInDragDrop){
            oldVertices.each(function(i,vertex){
                conn.addPoint(vertex);
            });
        	this._paint(conn);
            return;
        }
    	
    	//如果拖拽的是一个线段
    	if(conn.draggedSegment){
    		var index 		= conn.draggedSegment.index;
    		var newSegs		= new draw2d.util.ArrayList();
    		var newVertices = new draw2d.util.ArrayList();
    		
    		conn.getOldSegments().each(function(i,seg){
    			var tmp = {start:seg.start,end:seg.end};
    			newSegs.add(tmp);
    		});
    		
    		var oldSeg	= newSegs.get(index);
    		var preSeg	= newSegs.get(index-1);
    		var nxtSeg	= newSegs.get(index+1);
    		
    		//被拖拽的线段既有上一个线段又有下一个线段
    		if(preSeg && nxtSeg){
    			preSeg.end  = conn.draggedSegment.start;
    			nxtSeg.start= conn.draggedSegment.end;
    			oldSeg.start= conn.draggedSegment.start;
    			oldSeg.end  = conn.draggedSegment.end;
    		}
    		
    		newSegs.each(function(i,seg){
    			if(newSegs.last() === seg){
    				newVertices.add(seg.start);
    				newVertices.add(seg.end);    				
    			}else{
    				newVertices.add(seg.start);
    			}
    		});
    		
			newVertices.each(function(i,p){
				conn.addPoint(p);    		
			});  
			this._paint(conn);
    		return;
    	}
    	
    	//如果移动了源端口
    	if(routingHints.startMoved){
    		var sourcePt 	= source.getAbsolutePosition();
    		var targetPt 	= target.getAbsolutePosition();
    		var oldSourcePt = conn.getOldSegments().first().start;
    		
//    		if(sourcePt.equals(oldSourcePt)){
//    			return;
//    		}
    		
    		var newSegs     = new draw2d.util.ArrayList();
    		var newVertices = new draw2d.util.ArrayList();
    		conn.getOldSegments().each(function(i,seg){
    			var start = seg.start;
    			var end   = seg.end;
    			var type  = "";
    			var preSeg= null;
    			
    			if(i > 0){
    				preSeg = newSegs.get(i-1); 
    				if(!preSeg){
    					preSeg = {};
    					preSeg.end = seg.start;
    				}
    			}
    			
    			if(start.x === end.x){
    				type = 'v';
    			}else{
    				type = 'h';
    			}

    			var newEnd = null;
    			var newSeg = {};
    			if(i === 0){
    				newSeg = {start:sourcePt};
    			}
    			else if(preSeg){
    				newSeg = {start:preSeg.end};
    			}
				if(type === 'v'){
					newEnd = new draw2d.geo.Point(newSeg.start.x,seg.end.y);
				}else if(type === 'h'){
					newEnd = new draw2d.geo.Point(seg.end.x,newSeg.start.y);
				}
				newSeg.end = newEnd;
	    		if(newSeg.start.equals(newSeg.end)){
    				return;
    			}
				newSegs.add(newSeg);
    		});
    		var sameX = 1;
    		var sameY = 1;
    		newSegs.each(function(i,seg){
    			if(seg.start.x !== seg.end.x ){
    				sameX = 0;
    			}
    			if(seg.start.y !== seg.end.y){
    				sameY = 0;
    			}
    			if(newSegs.last() === seg){
    				newVertices.add(seg.start);
    				newVertices.add(seg.end);    				
    			}else{
        			if(sameX && sameY){
        				return true;
        			}
    				newVertices.add(seg.start);
    			}
    		});

    		if((sameY || sameX)&&(newVertices.getSize() >= 3)){
    			var newStart = newVertices.first();
    			var newEnd   = newVertices.last();
    			newVertices.clear();
    			newVertices.add(newStart);
    			newVertices.add(newEnd);
    		}
    		if((sameY || sameX || newVertices.getSize() < 3) && (newVertices.last().x !== targetPt.x || newVertices.last().y !== targetPt.y)){
    			newVertices.add(targetPt);  
    		}
    		
    		newVertices.each(function(i,p){
    			conn.addPoint(p);    		
    		});  
    		conn.saveOldSegmentsByVertices(newVertices);
        	
    		this._paint(conn);
    		return;
    	}
    	
    	//如果移动了目标端口
    	if(routingHints.endMoved){
    		var sourcePt 	= source.getAbsolutePosition();
    		var targetPt 	= target.getAbsolutePosition();
    		var oldTargetPt = conn.getOldSegments().last().end;

//    		if(targetPt.equals(oldTargetPt)){
//    			return;
//    		}
    		
    		var newSegs     = new draw2d.util.ArrayList();
    		var newVertices = new draw2d.util.ArrayList();
    		
    		var j=0;
    		for(var i=conn.getOldSegments().getSize()-1; i >= 0; i--){
    			var seg = conn.getOldSegments().get(i);
    			var start = seg.start;
    			var end   = seg.end;
    			var type  = "";
    			var preSeg= null;
    			
    			if(i < conn.getOldSegments().getSize()-1){
    				preSeg = newSegs.get(j++);   
    				if(!preSeg){
    					preSeg = {};
    					preSeg.start = conn.getOldSegments().get(i).end;
    				} 				
    			}
    			
    			if(start.x === end.x){
    				type = 'v';
    			}else{
    				type = 'h';
    			}
    			var newStart = null;
				var newSeg = {};
    			if(i === conn.getOldSegments().getSize()-1){
    				newSeg = {end:targetPt};
    			}
    			else if(preSeg){
    				newSeg = {end:preSeg.start};
    			}
				if(type === 'v'){
					newStart = new draw2d.geo.Point(newSeg.end.x,seg.start.y);
				}else if(type === 'h'){
					newStart = new draw2d.geo.Point(seg.start.x,newSeg.end.y);
				}
				newSeg.start = newStart;
	    		if(newSeg.start.equals(newSeg.end)){
    				continue;
    			}
				newSegs.add(newSeg);
    		}

	    	
    		newSegs.reverse();

    		var sameX = 1;
    		var sameY = 1;
    		newSegs.each(function(i,seg){
    			if(seg.start.x !== seg.end.x ){
    				sameX = 0;
    			}
    			if(seg.start.y !== seg.end.y){
    				sameY = 0;
    			}
    			if(newSegs.last() === seg){
    				newVertices.add(seg.start);
    				newVertices.add(seg.end);    				
    			}else{
        			if(sameX && sameY){
        				return true;
        			}
    				newVertices.add(seg.start);
    			}
    		});

    		//TODO:存在一个小问题，连线上存在结点会出现偏移 待优化~~~
    		if((sameY || sameX)&&(newVertices.getSize() >= 3)){
    			var newStart = newVertices.first();
    			var newEnd   = newVertices.last();
    			newVertices.clear();
    			newVertices.add(newStart);
    			newVertices.add(newEnd);
    		}
    		if((sameY || sameX || newVertices.getSize() < 3) && (newVertices.first().x !== sourcePt.x || newVertices.first().y !== sourcePt.y)){
    			newVertices.insertElementAt(sourcePt,0);   
    		}
    		
    		newVertices.each(function(i,p){
    			conn.addPoint(p);    		
    		});  
    		conn.saveOldSegmentsByVertices(newVertices);
        	
    		this._paint(conn);
    		return;
    	}
    	
    	var newVertices = new draw2d.util.ArrayList();
    	var newSegs = conn.getOldSegments();
    	newSegs.each(function(i,seg){
			if(newSegs.last() === seg){
				newVertices.add(seg.start);
				newVertices.add(seg.end);    				
			}else{
				newVertices.add(seg.start);
			}
    	});
    	newVertices.each(function(i,p){
			conn.addPoint(p);    		
		}); 
		this._paint(conn);
    },
});
